/**
 * 
 */
package com.kexinde.wjifen.util;

import java.lang.reflect.Constructor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据库连接池增删查改模版
 * 
 * @author vincent
 * @param <T>
 * 
 */
public class JdbcTemplate {

	/**
	 * 执行一条DML(insert，delete，update)
	 * 
	 * @param sql
	 *            预处理sql
	 * @param params
	 *            预处理参数对象数组
	 * @return 布尔值
	 */
	public static boolean executeUpdate(String sql, Object[] params)
			throws Exception {
		int result = 0;
		PreparedStatement pstmt = null;
		try {
			Connection conn = JdbcUtils.getConnection();
			pstmt = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				pstmt.setObject(i + 1, params[i]);
			}

			result = pstmt.executeUpdate();

		} catch (Exception e) {
			throw e;
		} finally {
			JdbcUtils.close(pstmt);
		}
		// System.out.println(result);
		return result >= 1 ? true : false;
	}

	/**
	 * 查询单个对象
	 * 
	 * @param <T>
	 *            要查询的对象类型
	 * @param ClassName
	 *            对象名
	 * @param sql
	 *            查询语句
	 * @param params
	 *            预处理参数
	 * @param fieldsCount
	 *            要返回的字段个数
	 * @return 返回对应类型对象
	 */
	public static <T> T query(String ClassName, String sql, Object[] params,
			int fieldsCount) throws Exception {
		T t = null;
		ResultSet rs = null;
		PreparedStatement pstmt = null;
		try {
			Connection conn = JdbcUtils.getConnection();
			pstmt = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				pstmt.setObject(i + 1, params[i]);
			}

			rs = pstmt.executeQuery();

			Class[] argsClass = new Class[fieldsCount];
			Object[] args = new Object[fieldsCount];

			while (rs.next()) {
				for (int i = 1; i <= fieldsCount; i++) {
					args[i - 1] = rs.getObject(i);
					if (args[i - 1] != null) {
						argsClass[i - 1] = args[i - 1].getClass();
					} else {
						argsClass[i - 1] = String.class;
					}
				}
			}
			Class cls = Class.forName(ClassName);
			Constructor cons = cls.getConstructor(argsClass);
			t = (T) cons.newInstance(args);

		} catch (Exception e) {
			throw e;
		} finally {
			JdbcUtils.close(rs);
			JdbcUtils.close(pstmt);
		}
		return t;
	}

	/**
	 * 查询记录条数
	 * 
	 * @param sql
	 *            预处理sql
	 * @param params
	 *            预处理参数
	 * @return 记录条数
	 */
	public static int count(String sql, Object[] params) throws Exception {
		int result = 0;
		ResultSet rs = null;
		PreparedStatement pstmt = null;
		try {
			Connection conn = JdbcUtils.getConnection();
			pstmt = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				pstmt.setObject(i + 1, params[i]);
			}

			rs = pstmt.executeQuery();

			while (rs.next()) {
				result = rs.getInt(1);
			}

		} catch (Exception e) {
			throw e;
		} finally {
			JdbcUtils.close(rs);
			JdbcUtils.close(pstmt);
		}
		// System.out.println(result);
		return result;
	}

	/**
	 * 查询某个对象集合
	 * 
	 * @param <T>
	 *            要查询的对象类型
	 * @param ClassName
	 *            对象名
	 * @param sql
	 *            查询语句
	 * @param params
	 *            预处理参数
	 * @param fieldsCount
	 *            要返回的字段个数
	 * @return 返回对应类型对象集合
	 */
	public static <T> List<T> queryList(String ClassName, String sql,
			Object[] params, int fieldsCount) throws Exception {
		List<T> list = new ArrayList<T>();
		ResultSet rs = null;
		PreparedStatement pstmt = null;
		try {
			Connection conn = JdbcUtils.getConnection();
			pstmt = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				pstmt.setObject(i + 1, params[i]);
			}

			rs = pstmt.executeQuery();

			Class[] argsClass = new Class[fieldsCount];
			Object[] args = new Object[fieldsCount];
			Class cls = Class.forName(ClassName);

			while (rs.next()) {
				for (int i = 1; i <= fieldsCount; i++) {
					args[i - 1] = rs.getObject(i);
					if (args[i - 1] != null) {
						argsClass[i - 1] = args[i - 1].getClass();
					} else {
						argsClass[i - 1] = String.class;
					}
				}
				Constructor cons = cls.getConstructor(argsClass);
				T t = (T) cons.newInstance(args);
				list.add(t);
			}

		} catch (Exception e) {
			throw e;
		} finally {
			JdbcUtils.close(rs);
			JdbcUtils.close(pstmt);
		}
		return list;

	}

}
